package com.yc.hundun.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 冉野 E-mail:yangtianrui135@163.com
 * @version 创建时间：2021/7/14 10:28 AM
 */
@ChannelHandler.Sharable
public class NettyServerHandler extends ChannelInboundHandlerAdapter {


    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);

    private ApplicationContext context;

    public NettyServerHandler(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {


        ByteBuf buf = (ByteBuf) msg;
        String recieved = getMessage(buf);
        final ServerCommand serverCommand = JSON.parseObject(recieved, ServerCommand.class);


        ServerResponse<Map<String, HashMap<String, ServerDomain>>> response;

        if (Objects.equals(ServerCommandType.REGISTER.name(), serverCommand.getServerType())) {
            serverCommand.getServerDomain().setLastHeartBeat(System.currentTimeMillis());
            // 注册
            Servers.put(serverCommand.getServerDomain());
            response =new ServerResponse ();
            response.setCode(1);

        } else {
            response = new ServerResponse<>();
            response.setCode(1);
            response.setData(Servers.getAll());
        }

        response.setType(serverCommand.getServerType());

        logger.info("服务端返回结果：[{}]", JSONObject.toJSONString(response));

        // 向客户端发送消息
        ctx.writeAndFlush(Unpooled.copiedBuffer((JSONObject.toJSONString(response)+  "\r\n").getBytes()));


    }


    enum ServerCommandType{
        REGISTER,
        CONNECT
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        // 打印 OutboundHandlerC -> OutboundHandlerB  ->  OutboundHandlerA 从尾部开始往前找 outbound
        ctx.channel().writeAndFlush("write in InBoundHandlerC");
        // 只打印 OutboundHandlerB  ->  OutboundHandlerA 从当前 handler 往前找 outbound
        // ctx.writeAndFlush("write in InBoundHandlerC");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        cause.printStackTrace();
        logger.error("服务器发生异常-------------->>");
        ctx.close();
    }

    private String getMessage(ByteBuf buf) {

        byte[] con = new byte[buf.readableBytes()];
        buf.readBytes(con);
        try {
            return new String(con, "UTF8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }
}
